import React, {
  useCallback,
  useMemo,
  useRef,
  useState,
  useLayoutEffect,
  Suspense,
  useEffect,
} from 'react';
import {
  View,
  TouchableOpacity,
  ScrollView,
  RefreshControl,
  ImageBackground,
  Pressable,
} from 'react-native';
import {useTranslation} from 'react-i18next';
import {useDispatch, useSelector} from 'react-redux';
import {
  fetchDeviceBySn,
  selectCurrentDevice,
  selectDeviceLoading,
  setDefaultStationId,
} from '@/store/slices/deviceSlice';
import type {AppDispatch} from '@/store';
import DeviceSkeleton from '@/components/DeviceList/DeviceSkeleton';
import {lazyLoad} from '@/utils/lazyLoad';
import {useNavigation} from '@react-navigation/native';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import NoDevice from '@/assets/icon/nodevice.svg';
import {Button, Icon, Text, useAppTheme} from 'tsun-smart-ui';
import {DeviceInfoProvider} from '@/components/DeviceInfo/DeviceInfoContext';
import {ComponentMap} from '@/components/DeviceList';
import {type StationDTO, stationApi} from '@/services/api/stationApi';
import {ModelAction} from '@/components/ActionSheets';
import {BottomSheetModal} from '@gorhom/bottom-sheet';
import {FlashList} from '@shopify/flash-list';
import {UserEquipmentDTO} from '@/services/api/deviceApi';
import eventBus from '@/utils/eventBus';
const Tag = ({
  children,
  type,
}: {
  children: React.ReactNode;
  type?: 'warning';
}) => {
  const theme = useAppTheme();
  return (
    <View
      className="h-10 flex-center rounded"
      style={{
        backgroundColor:
          type === 'warning'
            ? theme.colors?.brand?.primaryLight
            : theme.colors?.background?.primary,
      }}>
      <Text
        variant="bodyStrong"
        style={{
          color:
            type === 'warning'
              ? theme.colors?.brand?.primary
              : theme.colors?.neutral?.title,
        }}>
        {children}
      </Text>
    </View>
  );
};
const DevicePage = ({
  initialData: [initialStations],
}: {
  initialData: [StationDTO[]];
}) => {
  const {t} = useTranslation();
  const theme = useAppTheme();
  const scrollRef = useRef<ScrollView>(null);
  const {top} = useSafeAreaInsets();
  const [refreshing, setRefreshing] = useState(false);
  const navigation = useNavigation();
  const [stations, setStations] = useState<StationDTO[]>(initialStations);
  const dispatch = useDispatch<AppDispatch>();
  const bottomSheetRef = useRef<BottomSheetModal>(null);
  const currentDevice = useSelector(selectCurrentDevice);
  const loading = useSelector(selectDeviceLoading);

  const [empty, setEmpty] = useState(false);
  const assembleStationsWithDevices = useMemo(() => {
    const defaultStationId = stations.find(
      item => item.defaultCreate === 1,
    )?.id;
    dispatch(setDefaultStationId(defaultStationId));
    const result: (string | UserEquipmentDTO)[] = [];
    stations.forEach(station => {
      result.push(station.stationName);
      result.push(...(station.deviceDTOList || []));
    });
    return result;
  }, [stations]);
  const [selectedDevice, setSelectedDevice] = useState<number>(-1);
  useEffect(() => {
    const handler = () => {
      stationApi
        .getUserStations({
          pageSize: 999,
          pageNum: 1,
        })
        .then(res => {
          setStations(res.data.records);
        });
    };
    eventBus.on('DEVICE_CHANGE', handler);
    return () => {
      eventBus.off('DEVICE_CHANGE', handler);
    };
  }, []);
  useLayoutEffect(() => {
    const index = assembleStationsWithDevices.findIndex(
      item => typeof item === 'object',
    );
    setEmpty(index === -1);
    setSelectedDevice(index);
    const current = assembleStationsWithDevices[index] as
      | UserEquipmentDTO
      | undefined;
    if (current?.id !== currentDevice?.deviceId) {
      dispatch(
        fetchDeviceBySn({
          sn: current?.deviceSn!,
          stationId: current?.stationId!,
          deviceType: current?.deviceType!,
        }),
      );
    }
  }, [assembleStationsWithDevices]);
  const onRefresh = useCallback(() => {
    setRefreshing(true);
    dispatch(
      fetchDeviceBySn({
        sn: currentDevice?.sn!,
        stationId: currentDevice?.stationId!,
        deviceType: currentDevice?.deviceType!,
      }),
    )
      .unwrap()
      .finally(() => {
        setRefreshing(false);
      });
  }, [currentDevice]);
  return (
    <DeviceInfoProvider initialDeviceData={currentDevice}>
      <ImageBackground
        className="flex-1"
        imageStyle={{
          height: 294,
        }}
        source={theme.isDark ? null : require('@/assets/imgs/deviceInfo-bg.png')}>
        <View
          className="flex-row flex-between  px-4 absolute w-full z-50"
          style={{
            paddingTop: top + 20,
          }}>
          <TouchableOpacity
            className="flex-row items-center gap-x-2"
            onPress={() => {
              bottomSheetRef.current?.present();
            }}>
            <Text variant="navTitle">{currentDevice?.deviceName}</Text>
            {!empty && <Icon name="pull" size={16}></Icon>}
          </TouchableOpacity>

          <View className="flex-row gap-x-3">
            <Icon
              name="device-manage"
              size={24}
              onPress={() => {
                navigation.navigate('DeviceManage',{
                  setSelectedDevice,
                  assembleStationsWithDevices
                });
              }}></Icon>
            <Icon
              name="add"
              size={24}
              onPress={() => {
                navigation.navigate('SelectDeviceCategory');
              }}
            />
          </View>
        </View>
        {empty ? (
          <View className="flex-center flex-1 z-10">
            <NoDevice width={48}></NoDevice>
            <Text
              style={{
                color: theme.colors?.neutral?.tip,
              }}
              className="mb-6">
              {t('device.nodata')}
            </Text>

            <Button
              onPress={() => {
                navigation.navigate('SelectDeviceCategory');
              }}
              title={t('common.add.device')}
              icon={'add'}></Button>
          </View>
        ) : (
          <ScrollView
            ref={scrollRef}
            style={{
              marginTop: top + 62,
            }}
            contentContainerClassName="px-4 pb-4"
            showsVerticalScrollIndicator={false}
            refreshControl={
              <RefreshControl
                refreshing={refreshing}
                onRefresh={onRefresh}
                colors={[theme.colors?.brand?.primary!]}
                tintColor={theme.colors?.brand?.primary!}
                progressBackgroundColor={theme.colors?.background?.primary!}
              />
            }>
            {loading ? (
              <DeviceSkeleton />
            ) : (
              React.createElement(
                ComponentMap[currentDevice?.dvcType ?? 'inv'],
              )
            )}
          </ScrollView>
        )}
        <ModelAction
          ref={bottomSheetRef}
          height={478}
          title={t('device.select')}>
          <FlashList
            data={assembleStationsWithDevices}
            showsVerticalScrollIndicator={false}
            contentContainerStyle={{
              paddingHorizontal: 12,
            }}
            renderItem={({item, index}) => {
              if (typeof item === 'string') {
                // Rendering header - 独占一行
                return (
                  <Text
                    className="ml-1"
                    style={{marginTop: index ? 16 : 0}}
                    variant="bodyStrong">
                    {item}
                  </Text>
                );
              } else {
                // Render item - 平分2列
                return (
                  <Pressable
                    className="px-1 mt-2"
                    onPress={() => {
                      bottomSheetRef.current?.close();
                      dispatch(
                        fetchDeviceBySn({
                          sn: item.deviceSn,
                          stationId: item.stationId!,
                          deviceType: item.deviceType,
                        }),
                      )
                        .unwrap()
                        .then(() => {
                          setSelectedDevice(index);
                        });
                    }}>
                    <Tag
                      type={index === selectedDevice ? 'warning' : undefined}>
                      {item.deviceName}
                    </Tag>
                  </Pressable>
                );
              }
            }}
            overrideItemLayout={(layout, item) => {
              if (typeof item === 'string') {
                layout.span = 2;
              }
            }}
            numColumns={2}
            keyExtractor={(item, index) => {
              if (typeof item === 'string') {
                return `header-${index}`;
              } else {
                return `device-${index}`;
              }
            }}
          />
        </ModelAction>
      </ImageBackground>
    </DeviceInfoProvider>
  );
};
export default () => {
  const {top} = useSafeAreaInsets();
  const dispatch = useDispatch<AppDispatch>();
  const AsyncDevicePage = useMemo(() => {
    return lazyLoad({
      component: DevicePage,
      promises: [
        stationApi
          .getUserStations({
            pageSize: 999,
            pageNum: 1,
          })
          .then(async ({data}) => {
            const stations = data.records ?? [];
            for (const station of stations) {
              const deviceInfo = station.deviceDTOList?.[0];
              if (deviceInfo) {
                await dispatch(
                  fetchDeviceBySn({
                    sn: deviceInfo.deviceSn,
                    stationId: station.id!,
                    deviceType: deviceInfo.deviceType,
                  }),
                ).unwrap();
                return stations;
              }
            }
            return stations;
          }),
      ],
    });
  }, []);
  return (
    <Suspense
      fallback={
        <ScrollView
          contentContainerClassName="px-4 pb-4"
          style={{
            paddingTop: top,
          }}>
          <DeviceSkeleton></DeviceSkeleton>
        </ScrollView>
      }>
      <AsyncDevicePage></AsyncDevicePage>
    </Suspense>
  );
};
